package org.goldenport.g3.messages

import java.io._
import java.net.URL
import com.asamioffice.goldenport.io.UIO

/**
 * @since   May. 22, 2010
 * @version Jul. 25, 2010
 * @author  ASAMI, Tomoharu
 **/
abstract class Clob(val encoding: String = "utf-8") extends Blob {
  def openReader(): Reader

  def lengthOption(): Option[Long] = None

  def asString(): String = {
    val in = openReader()
    try {
      UIO.reader2String(in)
    } finally {
      in.close()
    }
  }

  def asStringOption(): Option[String] = {
    lengthOption match {
      case Some(length) if length <= IN_MEMORY_SIZE => Some(asString())
      case _ => None
    }
  }
}

class BinaryClob(val bytes: Array[Byte]) extends Clob {
  def openReader(): Reader = {
    new InputStreamReader(new ByteArrayInputStream(bytes), encoding)
  }

  def openInputStream(): InputStream = {
    new ByteArrayInputStream(bytes)
  }
}

class CharactersClob(val characters: Array[Char]) extends Clob {
  def openReader(): Reader = {
    new CharArrayReader(characters)
  }

  def openInputStream(): InputStream = {
    val bytes = new String(characters).getBytes(encoding)
    new ByteArrayInputStream(bytes)
  }
}

class FileClob(val file: File) extends Clob {
  def openReader(): Reader = {
    new InputStreamReader(new FileInputStream(file), encoding)
  }

  def openInputStream(): InputStream = {
    new FileInputStream(file)
  }
}

class UrlClob(val url: URL) extends Clob {
  def openReader(): Reader = {
    new InputStreamReader(url.openStream(), encoding)
  }

  def openInputStream(): InputStream = {
    url.openStream()
  }
}

/*
class ReaderClob(val reader: ReaderStream) extends Clob {
  def openReader(): BufferedReader = {
    reader
  }

  def openInputStream(): BufferedInputStream = {
    
  }
}
*/

class BlobClob(val blob: Blob, encoding: String) extends Clob(encoding) {
  def openReader(): Reader = {
    new InputStreamReader(blob.openInputStream(), encoding)
  }

  def openInputStream(): InputStream = {
    blob.openInputStream()
  }
}

object Clob {
  def apply(binary: Array[Byte]): BinaryClob = {
    new BinaryClob(binary)
  }

  def apply(chars: Array[Char]): CharactersClob = {
    new CharactersClob(chars)
  }

  def apply(file: File): FileClob = {
    new FileClob(file)
  }

  def apply(url: URL): UrlClob = {
    new UrlClob(url)
  }

/*
  def apply(reader: Reader): ReaderClob = {
    new ReaderClob(reader)
  }
*/
}
